/**
 ********************************************************************
 * @author roocket
 * @file    socket.c
 * @version V0.0.0
 * @date    2024/3/22
 * @brief   This file is to indicate socket functions. 
 * @attention Code file rules:
 * rule: file encoding use UTF8;
 * rule: max line length 120 characters;
 * rule: line separator \r\n;
 * rule: use clion auto code format tool.
 */
#include "socket.h"

int socket_client_init(const char *address, const unsigned short port)
{
    struct sockaddr_in addr;
    int fd = -1; 
    int err = -1;

    fd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == fd)
        return -1;

    memset(&addr, 0, sizeof(addr)); 
    addr.sin_family = AF_INET;  
    addr.sin_addr.s_addr = inet_addr(address);  
    addr.sin_port = htons(port);  

    err = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
    if (-1 == err) {
        printf("connect failed!!!\n");
        return -1;
    }
    printf("connect success!!!\n");
    return fd;
}

int socket_server_init(const char *address, const unsigned short port)
{
    struct sockaddr_in addr;
    int status;
    int size;
    socklen_t optlen;
    int err = -1;
    int fd = -1;

    fd = socket(AF_INET, SOCK_STREAM, 0);
    if(fd == -1) {
        perror("socket");
        exit(0);
    }

    addr.sin_port = htons(port);
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(address);

    /* set size for buffer */
    size = SOCKET_WR_MAX_STREAM_BUFFER;
    optlen = sizeof(SOCKET_WR_MAX_STREAM_BUFFER);
    err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&size, optlen);
    if (-1 == err)
        return -1;

    err = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&size, optlen);
    if (-1 == err)
        return -1;

    err = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&size, optlen);
    if (-1 == err)
        return -1;

    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &status, sizeof(int));

    err = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
    if (-1 == err) {
        perror("bind");
        return -1;
    }

    err = listen(fd, 100);
    if(-1 == err) {
        perror("listen");
        return -1;
    }
    return fd;
}

int socket_get_data(int fd, void *user)
{
    if (!user)
        return -1;

    return read(fd, user, SOCKET_WR_BUFER_LEN);
}

int socket_set_data(int fd, void *sent, int length)
{
    if (length <= 0 || !sent)
        return -1;

    return write(fd, sent, length);
}

void socket_del(int fd)
{
    if (fd > 0)
        close(fd);
}
